package com.printeverywhere.job;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.opensymphony.xwork2.ActionContext;
import com.printeverywhere.delegator.CommonFunctionDelegator;
import com.printeverywhere.delegator.ItemsServiceDelegator;
import com.printeverywhere.dto.AuctionBids;
import com.printeverywhere.dto.AuctionLostlist;
import com.printeverywhere.dto.AuctionWonlist;
import com.printeverywhere.dto.BidStatus;
import com.printeverywhere.dto.Items;
import com.printeverywhere.dto.MailingSystem;
import com.printeverywhere.dto.Transactions;
import com.printeverywhere.util.AdminConstants;
import com.printeverywhere.util.AttributeConstants;
import com.printeverywhere.util.CommonUtil;
import com.printeverywhere.util.DateUtil;
import com.printeverywhere.util.MailHelper;
import com.printeverywhere.util.SearchCriteria;
import com.printeverywhere.util.SearchListCriteria;

public class ProcessEndedAuctionsJob implements Job, ServletRequestAware{
	private static Logger logger = Logger.getLogger(ProcessEndedAuctionsJob.class);

	private List<Items> itemsList;

	private SearchListCriteria searchListCriteria = new SearchListCriteria();

	private SearchCriteria searchCriteria = new SearchCriteria();

	private HttpServletRequest request;

	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		try {
			/*Yet to decide which items should be included for processing*/
			BidStatus status = new BidStatus(5);
			searchListCriteria.removeAllAttribute();
			searchListCriteria.setAttribute("status", new Object[]{status, SearchListCriteria.NE});
			itemsList = ItemsServiceDelegator.getListBySearchListCriteria(searchListCriteria);
			for (Iterator<Items> iterator = itemsList.iterator(); iterator.hasNext();) {
				Items type = (Items) iterator.next();
				if(type.getEndTime().before(DateUtil.getTodaysDate())){
					List<AuctionBids> auctionBidsList = new ArrayList<AuctionBids>();
					searchCriteria.removeAllAttribute();
					searchCriteria.setAttribute(AttributeConstants.ITEMS, type);
					searchCriteria.setOrderBy("maxBid");
					searchCriteria.setAsc(false);
					auctionBidsList = (List<AuctionBids>) CommonFunctionDelegator.getObjectBySearchCriteria(searchCriteria, AuctionBids.class);
					int quantity = type.getQuantity();
					for (Iterator<AuctionBids> auctionIterator = auctionBidsList.iterator(); auctionIterator
							.hasNext();) {
						AuctionBids auctionBidsTemp = (AuctionBids) auctionIterator
								.next();
						if((quantity > 0) && (auctionBidsTemp.getBidQty() > 0) && (auctionBidsTemp.getMaxBid() > 0)){
							quantity = quantity - auctionBidsTemp.getBidQty();
							/* Inserting data for auction winner. */
							AuctionWonlist auctionWonlist = new AuctionWonlist();
							auctionWonlist.setUser(auctionBidsTemp.getUser());
							auctionWonlist.setItems(auctionBidsTemp.getItems());
							if(quantity < auctionBidsTemp.getBidQty()){
								auctionWonlist.setQuantity(quantity);
							}else{
								auctionWonlist.setQuantity(auctionBidsTemp.getBidQty());
							}
							auctionWonlist.setType(auctionBidsTemp.getItems().getItemtype().getId());
							auctionWonlist.setPrice(auctionBidsTemp.getMaxBid() * auctionBidsTemp.getBidQty());
							auctionWonlist
									.setPayed((auctionBidsTemp.getTime() != null && !auctionBidsTemp
											.getTime().equals(AdminConstants.NONE)) ? true
											: false);
							CommonFunctionDelegator.generalInsertbyobj(auctionWonlist);

							/* Inserting data to auction bids updating win Quantity */
							auctionBidsTemp.setWinQty(auctionWonlist.getQuantity().doubleValue());

							/* Inserting data in Transaction to keep record of transaction. */
							Transactions transactions = new Transactions();
							transactions.setAmount(auctionWonlist.getPrice());
							transactions.setDate(DateUtil.getTodaysDate());
							transactions.setTitle(auctionWonlist.getItems().getTitle());
							transactions.setId(auctionWonlist.getItems());
							transactions.setType(auctionWonlist.getItems().getItemtype().getId());
							transactions.setUser(auctionWonlist.getUser());

							CommonFunctionDelegator.generalInsertbyobj(transactions);

							/* Sending mail to auction winner */
							MailingSystem mailingSystem = (MailingSystem) ActionContext.getContext().getApplication().get(AdminConstants.MAILING_OPTIONS);
							MailHelper mailHelper = new MailHelper(mailingSystem.getServerAddress(), mailingSystem.getServerUsername(), mailingSystem.getServerPassword());

							StringBuffer URL = new StringBuffer();
							URL.append(CommonUtil.getLocalBasePath(request));
							URL.append("/mail/auctionWonMail.htm?username=").append(auctionWonlist.getUser().getUserId()).append("&quantity=").append(auctionWonlist.getQuantity());

							String message = CommonUtil.getURLContent(URL.toString());
							mailHelper.sendMail(mailingSystem.getAccountsConfirmationEmail(), auctionWonlist.getUser().getEmail(), "Auction won information", message);

							logger.info("Auction won mail has been sent to user: "+ auctionWonlist.getUser().getUserId());
						} else{
							/* Inserting user who did not meet auction. */
							AuctionLostlist auctionLostlist = new AuctionLostlist();
							auctionLostlist.setUser(auctionBidsTemp.getUser());
							auctionLostlist.setItems(type);
							auctionLostlist.setNote(auctionBidsTemp.getNote());
							CommonFunctionDelegator.generalInsertbyobj(auctionLostlist);

							/* Inserting data to auction bids updating win Quantity */
							auctionBidsTemp.setWinQty(0.0);
						}

						/* updating items status to closed. */
						BidStatus bidStatus = (BidStatus) CommonFunctionDelegator.getObjectById(AdminConstants.ID, 5, BidStatus.class);

						type.setStatus(bidStatus);
						CommonFunctionDelegator.generalUpdatebyobj(type);

						auctionBidsTemp.setBidStatus(bidStatus);
						CommonFunctionDelegator.generalUpdatebyobj(auctionBidsTemp);
					}
				}
			}
		} catch (Exception e) {
			logger.error("Error in processing eneded auctions.");
		}
	}

	public void setServletRequest(HttpServletRequest arg0) {
		request = arg0;

	}
}
